# 定制类
# Python的class中还有许多这样有特殊用途的函数，可以帮助我们定制类
# 1、__str__


class Student(object):
    def __init__(self, name):
        self.name = name


print(Student('jack'))  # 打印出一堆,不好看


class Student2(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        return 'Student2 object(name:%s)' % self.name

s = Student2('jackson')
print(s)

# 2、__iter__
# 如果一个类想被用于for ... in循环，类似list或tuple那样，就必须实现一个__iter__()方法，该方法返回一个迭代对象，然后，Python的for循环就会不断调用该迭代对象的__next__()方法拿到循环的下一个值，直到遇到StopIteration错误时退出循环


class Fib(object):
    def __init__(self):
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > 10000:
            raise StopIteration
        return self.b
for x in Fib():
    print(x)

# 3、__getitem__
# Fib实例虽然能作用于for循环，看起来和list有点像，但是，把它当成list来使用还是不行，比如，取第5个元素,要表现得像list那样按照下标取出元素，需要实现__getitem__()方法
class Fib2(object):
    def __init__(self):
        self.a, self.b = 0, 1

    def __iter__(self):
        return self

    def __next__(self):
        self.a, self.b = self.b, self.a + self.b
        if self.a > 10000:
            raise StopIteration
        return self.b

    def __getitem__(self, item):
        a, b = 1, 1
        for i in range(item):
            a, b = b, a + b
        return a

f = Fib2(10)
print(f[1])

